<?php
/**
 * Created by PhpStorm.
 * User: lhl
 * Date: 2019/5/31
 * Time: 13:40
 * Features: 文件及目录相关方法封装
 */

namespace app\common\service;


use think\facade\Cache;

class File
{
    //压缩包临时文件保存路径
    protected static $_zipSavePath = './download/temp/zip';

    /**
     * 获取文件锁
     * @param string $key
    */
    public static function lock($key,$timeout = 1){
        $cache = Cache::get($key);
        if(!$cache){
            Cache::set($key,1,$timeout);
            return true;
        }else{
            return false;
        }
    }

    /**
     * 读取文件
     * @param string $path 文件目录
    */
    public static function read($path){
        if(file_exists($path)) {
            $fp = fopen($path, "r");
            if($fp){
                $str = "";
                while (!feof($fp)) {
                    $str .= fgets($fp,4096);//逐行读取。
                }
                fclose($fp);
                return $str;
            }
        }
        return false;
    }

    /**
     * 递归创建目录
     * @param string $path  目录路径
     * @return bool
     */
    public static function createDir($path){
       return  is_dir($path) or self::createDir(dirname($path)) and mkdir($path, 0777);
    }

    /**
     * 递归删除目录及目录下所有文件或删除指定文件
     * @param string $path   待删除目录路径
     * @param mixed $delDir 是否删除目录，1或true删除目录，0或false则只删除文件保留目录（包含子目录）
     * @return bool 返回删除状态
     */
    public static function delDir($path,$delDir = false) {
        $handle = opendir($path);
        if ($handle) {
            while (false !== ($item = readdir($handle))) {
                if ($item != "." && $item != "..")
                    is_dir("$path/$item") ? self::delDir("$path/$item", $delDir) : unlink("$path/$item");
            }
            closedir($handle);
            if ($delDir)
                return rmdir($path);
            else
                return true;
        }else {
            if (file_exists($path)) {
                return unlink($path);
            } else {
                return false;
            }
        }
    }

    /**
     * 递归获取文件夹下的所有文件名
     * @param string $path 目录路径
     * @return array
    */
    public static function getDirFiles($path) {
        static $files;
        if ($handle = opendir(realpath($path))) {
            while (false !== ($file = readdir($handle))) {
                if ($file === '.' || $file === '..') {
                    continue;
                }
                $this_file = $path . '/' . $file;
                if (is_file($this_file)) {
                    $files[] = $this_file;

                }
                if (is_dir($this_file)) {
                    self::getDirFiles($this_file);
                }
            }

            closedir($handle);
        }
        return $files;
    }

    /**
    * 下载临时文件并删除
    * @param string $path 文件路径
   */
    public static function download($path){
       if (file_exists($path)) {
           header('Content-Description: File Transfer');
           header('Content-Type: application/octet-stream');
           header('Content-Disposition: attachment; filename='.basename($path));
           header('Content-Transfer-Encoding: binary');
           header('Expires: 0');
           header('Cache-Control: must-revalidate');
           header('Pragma: public');
           header('Content-Length: ' . filesize($path));
           ob_clean();
           flush();
           readfile($path);
           unlink($path);
       }
       exit;
   }

    /**
     * 多文件压缩包下载
     * @param array $files 需要压缩的文件的完整路径,不能包含中文 ['路径1','路径2',...]
     * @param string $zipName 压缩包名称不填则以默认文件名下载
     * @param bool $isDelFiles 是否删除文件群
     */
    public static function downloadZip($files,$zipName = '',$isDelFiles = false){
        //压缩包名称
        $zipName = strlen($zipName) ? $zipName.'.zip' : date('YmdHis').rand(0000,9999).".zip";
        $zipName =  iconv('utf-8', 'gb2312', $zipName); //文件名gb2312编码,避免中文报错
        $zipName = rtrim(self::$_zipSavePath,'/').'/'.$zipName;
        $zip = new \ZipArchive();
        $zip->open($zipName,\ZipArchive::CREATE); //打开压缩包,此处就已经创建了一个压缩包文件
        //将文件添加进压缩包
        foreach ($files as $item){
            $zip->addFile($item,strrchr($item,'/')); //截取文件名 返回从某个字符串在另一个字符串中最后一次出现的位置到主字符串结尾的所有字符。
        }
        //关闭压缩包
        $zip->close();
        if($isDelFiles){
            foreach ($files as $item){
                unlink($item);
            }
        }

        $data = file_get_contents($zipName);
        //下载压缩包
        header('Content-Description: File Transfer');
        header("content-type:application/x-zip-compressed");
        header('Content-Disposition: attachment; filename='.basename($zipName));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($zipName));
        ob_clean();   //清空但不关闭输出缓存
        flush();
        unlink($zipName);//删除打包的临时zip文件。文件会在用户下载完成后被删除
        exit($data);
    }
}